home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-19
/
intrlib1.zip
/
SAVEIMAG.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-20
|
13KB
|
367 lines
/******************************************************************************
* Iteraction library - save/restore bitmaps. *
* *
* Written by Gershon Elber, Oct. 1990 *
*******************************************************************************
* History: *
* 3 Oct 90 - Version 1.0 by Gershon Elber. *
******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#ifdef __MSDOS__
#include <sys\stat.h>
#endif /* __MSDOS__ */
#include "intr_loc.h"
#include "intr_gr.h"
#ifdef __MSDOS__
#include "intr_ems.h"
#endif /* __MSDOS__ */
#define MAX_NUM_SAVE_IMAGE 20
#define MAX_ASYNC_EVENTS (MAX_NUM_SAVE_IMAGE - 5)
typedef struct IntrSaveMemStruct {
struct IntrSaveMemStruct *Pnext; /* If has more save mem. structs. */
int Xmin, Ymin, Xmax, Ymax;
int Handle, LineSize, NumOfLines, LinesPerPage;
union {
void *Buffer; /* Pointer to real memory buffer if in real memory. */
char *FileName; /* Pointer to full path file name if save on disk. */
#ifdef DJGCC
void *Region;/* struct GrRegion actually, but hidden by intr_djg.cc. */
#endif /* DJGCC */
} U;
} IntrSaveMemStruct;
/* If _IntrSaveBelow is TRUE, the image below the pop up window is saved and */
/* restored once done. This requires the usage of temporary memory. */
/* If _IntrSaveBelow is FALSE, the windows below should be refreshed. This */
/* is usually slower but no image saving is required. */
IntrBType _IntrSaveBelow = TRUE;
static IntrSaveMemType
SaveMemMethod = INTR_SAVE_CONV,
AllowAsyncEvents = FALSE;
static char
*TempFileName = "Intr$Tmp.SM1",
*TempFilePath = NULL;
static int
NumOfSavedImages = 0;
static IntrSaveMemStruct
*SaveMemAllRoots[MAX_NUM_SAVE_IMAGE];
/****************************************************************************
* Function to control if internal events are to be handled. *
****************************************************************************/
IntrBType _IntrAllowInternalEvent(void)
{
if (NumOfSavedImages == 0) return TRUE;
return AllowAsyncEvents && NumOfSavedImages < MAX_ASYNC_EVENTS;
}
/****************************************************************************
* Function to control if internal events are to be handled. *
****************************************************************************/
void IntrSetAsyncEventMode(IntrBType AsyncMode)
{
AllowAsyncEvents = AsyncMode;
}
/****************************************************************************
* Function returns number of pop up items. *
****************************************************************************/
int IntrPopUpActive(void)
{
return NumOfSavedImages;
}
/****************************************************************************
* Set back saving flag. *
****************************************************************************/
void IntrSetSaveBackGround(IntrBType SaveBackGround)
{
if (NumOfSavedImages > 0)
IntrFatalError("Can not change image save method while image saved.");
_IntrSaveBelow = SaveBackGround;
}
/****************************************************************************
* Set back saving method. See IntrSameMemType for methods. *
****************************************************************************/
void IntrSetSaveBackMethod(IntrSaveMemType SaveBackMethod)
{
if (NumOfSavedImages > 0)
IntrFatalError("Can not change image save method while image saved.");
SaveMemMethod = SaveBackMethod;
switch(SaveMemMethod) {
case INTR_SAVE_CONV:
break;
#ifdef __MSDOS__
case INTR_SAVE_EMS:
if (!EMSDetected())
IntrFatalError("EMS driver not detected.");
break;
case INTR_SAVE_XMS:
IntrFatalError("XMS not implemented.");
break;
case INTR_SAVE_DISK:
break;
#endif /* __MSDOS__ */
}
}
/****************************************************************************
* Set path to save images on disk. Default is current directory. *
* This path is used to save images if method is INTR_SAVE_DISK. *
****************************************************************************/
void IntrSetSaveBackPath(char *Path)
{
if (NumOfSavedImages > 0)
IntrFatalError("Can not change image save method while image saved.");
if (TempFilePath != NULL) _IntrFree(TempFilePath);
if (Path != NULL)
TempFilePath = strdup(Path);
else
TempFilePath = NULL;
}
/****************************************************************************
* Saves the content of the image buffer specified by the BBox below. *
****************************************************************************/
void _IntrSaveWindow(int Xmin, int Ymin, int Xmax, int Ymax)
{
void *Buffer;
char Name[80];
int Handle, y, Page;
unsigned long Size;
unsigned int NumOfPages, LinesInOne, YmaxTmp, LineSize;
IntrSaveMemStruct *SaveMem,
*SaveMemRoot = NULL,
*SaveMemTail = NULL;
if (Xmin < 0) Xmin = 0;
if (Ymin < 0) Ymin = 0;
if (Xmax > GRScreenMaxX) Xmax = GRScreenMaxX;
if (Ymax > GRScreenMaxY) Ymax = GRScreenMaxY;
if (NumOfSavedImages >= MAX_NUM_SAVE_IMAGE)
IntrFatalError("Save image stack overflow.");
#ifdef __MSDOS__
Size = (unsigned long) GRGetImageBufferSize(Xmin, Ymin, Xmax, Ymax);
LineSize = GRGetImageBufferSize(Xmin, 0, Xmax, 0);
/* Size is bigger than 64k - find real size. */
if (Size == 0xffffL)
Size = (Ymax - Ymin) * ((unsigned long) LineSize);
#endif /* __MSDOS__ */
switch (SaveMemMethod) {
default:
case INTR_SAVE_CONV:
#ifdef __MSDOS__
if (Size > 0xffffL) { /* Need to save in parts. */
LinesInOne = 32767 / LineSize; /* Approx. 32k each time. */
while (Ymin < Ymax) {
SaveMem = (IntrSaveMemStruct *)
_IntrMalloc(sizeof(IntrSaveMemStruct));
SaveMem -> Pnext = NULL;
SaveMem -> Xmin = Xmin;
SaveMem -> Ymin = Ymin;
SaveMem -> Xmax = Xmax;
SaveMem -> Ymax = Ymax;
YmaxTmp = MIN(Ymin + LinesInOne, Ymax);
SaveMem -> U.Buffer =
_IntrMalloc(GRGetImageBufferSize(Xmin, Ymin,
Xmax, YmaxTmp));
GRGetImageBuffer(Xmin, Ymin, Xmax, YmaxTmp,
SaveMem -> U.Buffer);
Ymin = YmaxTmp;
if (SaveMemRoot != NULL) {
SaveMemTail -> Pnext = SaveMem;
SaveMemTail = SaveMem;
}
else {
SaveMemRoot = SaveMemTail = SaveMem;
}
}
}
else
#endif /* __MSDOS__ */
{
SaveMemRoot = (IntrSaveMemStruct *)
_IntrMalloc(sizeof(IntrSaveMemStruct));
SaveMemRoot -> Pnext = NULL;
SaveMemRoot -> Xmin = Xmin;
SaveMemRoot -> Ymin = Ymin;
SaveMemRoot -> Xmax = Xmax;
SaveMemRoot -> Ymax = Ymax;
#ifdef __MSDOS__
SaveMemRoot -> U.Buffer = _IntrMalloc((unsigned int) Size);
GRGetImageBuffer(Xmin, Ymin, Xmax, Ymax,
SaveMemRoot -> U.Buffer);
#endif /* __MSDOS__ */
#ifdef DJGCC
SaveMemRoot -> U.Region = GRGetImageBuffer(Xmin, Ymin,
Xmax, Ymax);
#endif /* DJGCC */
}
break;
#ifdef __MSDOS__
case INTR_SAVE_EMS:
LinesInOne = 15000 / LineSize; /* Approx. 15k in page. */
NumOfPages = (Ymax - Ymin + 1) / LinesInOne + 1;
if (NumOfPages > 1)
printf("");
SaveMemRoot = (IntrSaveMemStruct *)
_IntrMalloc(sizeof(IntrSaveMemStruct));
if ((SaveMemRoot -> Handle = EMSAlloc(NumOfPages)) == 0)
IntrFatalError("Fail to EMS allocate.");
SaveMemRoot -> Pnext = NULL;
SaveMemRoot -> Xmin = Xmin;
SaveMemRoot -> Ymin = Ymin;
SaveMemRoot -> Xmax = Xmax;
SaveMemRoot -> Ymax = Ymax;
SaveMemRoot -> LineSize = LineSize;
SaveMemRoot -> NumOfLines = Ymax - Ymin + 1;
SaveMemRoot -> LinesPerPage = LinesInOne;
Page = 0;
while (Ymin < Ymax) {
if ((Buffer = EMSMap(SaveMemRoot -> Handle, Page++, 0)) == NULL)
IntrFatalError("Fail to EMS Map.");
YmaxTmp = MIN(Ymin + LinesInOne - 1, Ymax);
GRGetImageBuffer(Xmin, Ymin, Xmax, YmaxTmp, Buffer);
Ymin += LinesInOne;
}
break;
case INTR_SAVE_XMS:
break;
case INTR_SAVE_DISK:
/* Save into disk one line at a time. */
if (TempFilePath != NULL)
strcpy(Name, TempFilePath);
else
Name[0] = 0;
strcat(Name, TempFileName);
Name[strlen(Name) - 1] = 'A' + NumOfSavedImages;
if ((Handle = open(Name,
O_RDWR | O_CREAT | O_BINARY,
S_IREAD | S_IWRITE)) < 0)
IntrFatalError("Fail to open image disk file.");
Buffer = _IntrMalloc(LineSize);
SaveMemRoot = (IntrSaveMemStruct *)
_IntrMalloc(sizeof(IntrSaveMemStruct));
SaveMemRoot -> Pnext = NULL;
SaveMemRoot -> Xmin = Xmin;
SaveMemRoot -> Ymin = Ymin;
SaveMemRoot -> Xmax = Xmax;
SaveMemRoot -> Ymax = Ymax;
SaveMemRoot -> LineSize = LineSize;
SaveMemRoot -> NumOfLines = Ymax - Ymin + 1;
SaveMemRoot -> U.FileName = strdup(Name);
for (y = Ymin; y <= Ymax; y++) {
GRGetImageBuffer(Xmin, y, Xmax, y, Buffer);
write(Handle, Buffer, LineSize);
}
_IntrFree(Buffer);
close(Handle);
break;
#endif /* __MSDOS__ */
}
SaveMemAllRoots[NumOfSavedImages++] = SaveMemRoot;
}
/****************************************************************************
* Free all saved images in case of async. exit. *
****************************************************************************/
void _IntrRestoreAll(void)
{
while (NumOfSavedImages > 0) _IntrRestoreWindow();
}
/****************************************************************************
* Restores the content of the image buffer specified by SaveMemRoot. *
****************************************************************************/
void _IntrRestoreWindow(void)
{
int Handle, y, LinesPerPage, Page;
void *Buffer;
IntrSaveMemStruct *SaveMem, *SaveMemRoot;
if (NumOfSavedImages <= 0)
IntrFatalError("Save image stack underflow.");
SaveMemRoot = SaveMemAllRoots[--NumOfSavedImages];
switch (SaveMemMethod) {
default:
case INTR_SAVE_CONV:
while (SaveMemRoot != NULL) {
SaveMem = SaveMemRoot;
SaveMemRoot = SaveMemRoot -> Pnext;
#ifdef __MSDOS__
GRPutImageBuffer(SaveMem -> Xmin, SaveMem -> Ymin,
SaveMem -> U.Buffer);
_IntrFree(SaveMem -> U.Buffer);
#endif /* __MSDOS__ */
#ifdef DJGCC
GRPutImageBuffer(SaveMem -> Xmin, SaveMem -> Ymin,
SaveMem -> U.Region);
#endif /* DJGCC */
_IntrFree(SaveMem);
}
break;
#ifdef __MSDOS__
case INTR_SAVE_EMS:
y = SaveMemRoot -> Ymin;
LinesPerPage = SaveMemRoot -> LinesPerPage;
Page = 0;
while (y < SaveMemRoot -> Ymax) {
if ((Buffer = EMSMap(SaveMemRoot -> Handle, Page++, 0)) == NULL)
IntrFatalError("Fail to EMS Map.");
GRPutImageBuffer(SaveMemRoot -> Xmin, y, Buffer);
y += LinesPerPage;
}
EMSFree(SaveMemRoot -> Handle);
_IntrFree(SaveMemRoot);
break;
case INTR_SAVE_XMS:
break;
case INTR_SAVE_DISK:
/* Read from disk one line at a time. */
Buffer = _IntrMalloc(SaveMemRoot -> LineSize);
if ((Handle = open(SaveMemRoot -> U.FileName,
O_RDONLY | O_BINARY,
S_IREAD)) < 0)
IntrFatalError("Fail to open image disk file.");
for (y = SaveMemRoot -> Ymin; y <= SaveMemRoot -> Ymax; y++) {
read(Handle, Buffer, SaveMemRoot -> LineSize);
GRPutImageBuffer(SaveMemRoot -> Xmin, y, Buffer);
}
_IntrFree(Buffer);
close(Handle);
unlink(SaveMemRoot -> U.FileName); /* Delete the file. */
_IntrFree(SaveMemRoot -> U.FileName);
_IntrFree(SaveMemRoot);
break;
#endif /* __MSDOS__ */
}
}